/* $Id: AdminNonClientCompanyReviewFacadeImpl.java 
 * Copyright (C) 2011, TRAKHEES
 *  
 * Revision History
 *
 * Date  			Author 		    	Remarks
 * ---------------------------------------------------------------------------------
 *
 */
package ae.pcfc.etks.online.common.facade.provider;

import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import ae.pcfc.etks.online.common.ConstantsCommon;
import ae.pcfc.etks.online.common.domain.AppMetaData;
import ae.pcfc.etks.online.common.domain.ClientCompanyReq;
import ae.pcfc.etks.online.common.domain.ClientCompanyRoleReq;
import ae.pcfc.etks.online.common.domain.TTscCity;
import ae.pcfc.etks.online.common.domain.TTscClientCategory;
import ae.pcfc.etks.online.common.domain.TTscClientRole;
import ae.pcfc.etks.online.common.domain.TTscCountry;
import ae.pcfc.etks.online.common.domain.TTscLicIssuingAuthority;
import ae.pcfc.etks.online.common.domain.TTscLicType;
import ae.pcfc.etks.online.common.domain.manager.AppMetaDataDomainObjectManager;
import ae.pcfc.etks.online.common.domain.manager.NonClientCompanyDomainObjectManager;
import ae.pcfc.etks.online.common.domain.manager.ProcessStepActionDomainObjectManager;
import ae.pcfc.etks.online.common.domain.manager.SingleClientCompanyDomainObjectManager;
import ae.pcfc.etks.online.common.domain.manager.SingleClientRoleObjectManager;
import ae.pcfc.etks.online.common.domain.manager.UtilityDomainObjectManager;
import ae.pcfc.etks.online.common.exception.InvalidInputException;
import ae.pcfc.etks.online.common.facade.AdminNonClientCompanyReviewFacade;
import ae.pcfc.etks.online.common.vo.AdminApprovalVO;
import ae.pcfc.etks.online.common.vo.NonClientCompanyVO;
import ae.pcfc.etks.online.wf.ConstantsWF;
import ae.pcfc.etks.online.wf.service.client.NonClientWF;
import ae.pcfc.etks.online.wf.service.client.vo.NonClientCompleteStepVO;

public class AdminNonClientCompanyReviewFacadeImpl extends BaseFacade implements AdminNonClientCompanyReviewFacade {

    	/*
	 * Here we coordinate between the all interacting business domain objects
	 * (BO), transactions are maintained here. use case business validation are
	 * maintained here (that requires DB checks or retrieving data from DB)
	 */
	private NonClientCompanyDomainObjectManager nonClientCompanyDomainObjectManager;
	private SingleClientRoleObjectManager singleClientRoleObjectManager;
	private SingleClientCompanyDomainObjectManager singleClientCompanyDomainObjectManager;
	private AppMetaDataDomainObjectManager appMetaDataDomainObjectManager;
	private NonClientWF nonClientCompanyWF;
	private UtilityDomainObjectManager utilityDomainObjectManager;
	private ProcessStepActionDomainObjectManager processStepActionDomainObjectManager;

	public void setNonClientCompanyWF(NonClientWF nonClientCompanyWF) {
		this.nonClientCompanyWF = nonClientCompanyWF;
	}

	public ProcessStepActionDomainObjectManager getProcessStepActionDomainObjectManager() {
		return processStepActionDomainObjectManager;
	}

	public void setProcessStepActionDomainObjectManager(
			ProcessStepActionDomainObjectManager processStepActionDomainObjectManager) {
		this.processStepActionDomainObjectManager = processStepActionDomainObjectManager;
	}

	public void setSingleClientRoleObjectManager(SingleClientRoleObjectManager singleClientRoleObjectManager) {
		this.singleClientRoleObjectManager = singleClientRoleObjectManager;
	}

	public void setSingleClientCompanyDomainObjectManager(
			SingleClientCompanyDomainObjectManager singleClientCompanyDomainObjectManager) {
		this.singleClientCompanyDomainObjectManager = singleClientCompanyDomainObjectManager;
	}

	public void setAppMetaDataDomainObjectManager(AppMetaDataDomainObjectManager appMetaDataDomainObjectManager) {
		this.appMetaDataDomainObjectManager = appMetaDataDomainObjectManager;
	}

	public void setNonClientCompanyDomainObjectManager(NonClientCompanyDomainObjectManager nonClientCompanyDomainObjectManager) {
		this.nonClientCompanyDomainObjectManager = nonClientCompanyDomainObjectManager;
	}
	
	public void setUtilityDomainObjectManager(UtilityDomainObjectManager utilityDomainObjectManager) {
		this.utilityDomainObjectManager = utilityDomainObjectManager;
	}

	/**
	 * getNonClientCompanyByApplicationId
	 * 
	 * @see ae.pcfc.etks.online.common.facade.AdminNonClientCompanyReviewFacade#getNonClientCompanyByApplicationId(java.lang.String)
	 * 
	 */
	@Transactional(readOnly = true)
	public NonClientCompanyVO getNonClientCompanyByApplicationId(String applicationId) {

		ClientCompanyReq clientCompanyReq = nonClientCompanyDomainObjectManager.getNonClientCompanyByApplicationId(applicationId);
		
		if (clientCompanyReq != null) {
			

			NonClientCompanyVO nonClientCompanyVO = new NonClientCompanyVO();
			TTscClientRole tscClientRole = null;
			
			for (ClientCompanyRoleReq companyRole : clientCompanyReq.getClientCompanyRoleReqs()) {
				
						
				tscClientRole = new TTscClientRole();
				tscClientRole = singleClientRoleObjectManager.getClientRoleByRoleId(companyRole.getCsrReqId().toString());
				
				if(nonClientCompanyVO.getStrClientRoleEn() != null )
				{
					nonClientCompanyVO.setStrClientRoleEn(nonClientCompanyVO.getStrClientRoleEn()+","+tscClientRole.getCrDesc());
				}else
				{
					nonClientCompanyVO.setStrClientRoleEn(tscClientRole.getCrDesc());
				}
				if(nonClientCompanyVO.getStrClientRoleAr() != null)
				{
					nonClientCompanyVO.setStrClientRoleAr(nonClientCompanyVO.getStrClientRoleAr()+","+tscClientRole.getCrDescArb());
				
				}else
				{
					nonClientCompanyVO.setStrClientRoleAr(tscClientRole.getCrDescArb());
				}
			}

			
			if(clientCompanyReq != null)
			{
				getMapper().map(clientCompanyReq, nonClientCompanyVO);
			}
			
			if(tscClientRole != null)
			{
				getMapper().map(tscClientRole, nonClientCompanyVO);
			}
			
			if(clientCompanyReq.getCcCategory() != null)
			{
				TTscClientCategory clientCategory = this.singleClientCompanyDomainObjectManager.getClientCategoryById(clientCompanyReq.getCcCategory());
				
				getMapper().map(clientCategory, nonClientCompanyVO);
			}
			
			if(clientCompanyReq.getCcLicType() != null)
			{
				TTscLicType licType = this.singleClientCompanyDomainObjectManager.getClientLicenseTypeByCode(clientCompanyReq.getCcLicType());
				
				getMapper().map(licType, nonClientCompanyVO);
			}
			
			if(clientCompanyReq.getCcLicIssuingAuthority() != null)
			{
				TTscLicIssuingAuthority licIssuingAuthority = this.utilityDomainObjectManager.getLicIssuingAuthorityByCode(clientCompanyReq.getCcLicIssuingAuthority());
				
				if(licIssuingAuthority != null)
				{
					getMapper().map(licIssuingAuthority, nonClientCompanyVO);
				}
			}
			
			if(clientCompanyReq.getCcCity() != null)
			{
				TTscCity city = this.utilityDomainObjectManager.getCityByCode(clientCompanyReq.getCcCity());
				
				if(city != null)
				{
					getMapper().map(city, nonClientCompanyVO);
				}
			}
			
			if(clientCompanyReq.getCcCountry() != null)
			{
				TTscCountry  country = this.utilityDomainObjectManager.getCountryByCode(clientCompanyReq.getCcCountry());
				
				if(country != null)
				{
					getMapper().map(country, nonClientCompanyVO);
				}
			}
			
			return nonClientCompanyVO;	
		} 	
		
		return null;
	}

	/**
	 * reviewNonClientCompany
	 * @return 
	 * 
	 * @see ae.pcfc.etks.online.common.facade.AdminNonClientCompanyReviewFacade#reviewNonClientCompany(ae.pcfc.etks.online.common.vo.AdminApprovalVO, java.lang.String)
	 * 
	 */
	@Transactional
	public NonClientCompleteStepVO reviewNonClientCompany(AdminApprovalVO adminApprovalVO, String strUserName) {
		AppMetaData appMetaData = appMetaDataDomainObjectManager.findByPrimaryKeyProcessAndStepCode(adminApprovalVO.getStrApplicationId().toString(), adminApprovalVO.getProcessCode().getProcessCode(), adminApprovalVO.getStrStepName());

		if (appMetaData != null) {
			/************ Storing Meta Data in Tables ***********************/
            	    	if(appMetaDataDomainObjectManager.validateAppMetaDataWithStep(appMetaData,adminApprovalVO.getStrStepName())){
        	    	    throw new InvalidInputException();
        	    	}		    
			String wfStatusEn = appMetaData.getWfStatusEn();
		String wfStatusAr = appMetaData.getWfStatusAr();
		
		getMapper().map(adminApprovalVO, appMetaData);
		
		appMetaData.setWfStatusEn(wfStatusEn);
		appMetaData.setWfStatusAr(wfStatusAr);
			this.appMetaDataDomainObjectManager.updateAppMetaDataWithActionTaken(appMetaData, adminApprovalVO.getStrStepName());
			/************** End Store Meta Date ***************************/
			ClientCompanyReq clientCompanyReq = nonClientCompanyDomainObjectManager.getNonClientCompanyByApplicationId(adminApprovalVO.getStrApplicationId());
			clientCompanyReq.setCpCreatedUser(StringUtils.remove(strUserName, ConstantsWF.USER_PREFIX));
			NonClientCompleteStepVO completeStepVO = getCompleteStepVO(adminApprovalVO, appMetaData, clientCompanyReq, strUserName);

			if(nonClientCompanyWF.getFinDeptStepName().equalsIgnoreCase(adminApprovalVO.getStrStepName()) && adminApprovalVO.getStrActionType().equals(ConstantsCommon.APPROVE)){
			    	// If Approved by Finance department, send the approval message to the Ultimus alone and update the application request in the DB as approved
					Map<String, String> valuesMap = singleClientCompanyDomainObjectManager.add(clientCompanyReq);
				    completeStepVO.setgTKSID(valuesMap.get(ConstantsCommon.TRAKHEES_ID));
				    completeStepVO.setgPin(valuesMap.get(ConstantsCommon.PIN_CODE));
				    clientCompanyReq.setCcStatus(adminApprovalVO.getStrActionType());
				    nonClientCompanyDomainObjectManager.update(clientCompanyReq);
        			appMetaData.setWfStatus(ConstantsCommon.APPROVE);
        			appMetaData.setWfStatusEn(adminApprovalVO.getStrStatusEn());
        			appMetaData.setWfStatusAr(adminApprovalVO.getStrStatusAr());
        			nonClientCompanyWF.updateCompleteStepVO(completeStepVO, adminApprovalVO.getStrStepName(), ConstantsCommon.WORK_FLOW_STATUS_APPROVE, adminApprovalVO.getStrUserNotification());
			}else if(adminApprovalVO.getStrActionType().equals(ConstantsCommon.APPROVE)){
			    	// If Approved by any other departments, send the approval message to the Ultimus alone
				nonClientCompanyWF.updateCompleteStepVO(completeStepVO, adminApprovalVO.getStrStepName(), ConstantsCommon.WORK_FLOW_STATUS_APPROVE, adminApprovalVO.getStrUserNotification());
			}else if(adminApprovalVO.getStrActionType().equals(ConstantsCommon.REJECT)){
			    	// If Rejected, update the application request in DB as rejected and send the rejection message to the Ultimus
				    clientCompanyReq.setCcStatus(ConstantsCommon.REJECT);
				    nonClientCompanyDomainObjectManager.update(clientCompanyReq);
			    	appMetaData.setWfStatus(ConstantsCommon.REJECT);
					appMetaData.setWfStatusEn(adminApprovalVO.getStrStatusEn());
					appMetaData.setWfStatusAr(adminApprovalVO.getStrStatusAr());
					nonClientCompanyWF.updateCompleteStepVO(completeStepVO, adminApprovalVO.getStrStepName(), ConstantsCommon.WORK_FLOW_STATUS_REJECT, adminApprovalVO.getStrUserNotification());
			}
			appMetaDataDomainObjectManager.update(appMetaData);
			return completeStepVO;
		}
		
		return null;
	}
	
	private NonClientCompleteStepVO getCompleteStepVO(AdminApprovalVO adminApprovalVO, AppMetaData appMetaData, ClientCompanyReq clientCompanyReq, String strUserName) {
		NonClientCompleteStepVO completeStepVO = new NonClientCompleteStepVO();
		completeStepVO.setgApplicationID(adminApprovalVO.getStrApplicationId());
		completeStepVO.setgClientReference(appMetaData.getClientRefNo());
		completeStepVO.setStrStepName(adminApprovalVO.getStrStepName());
		completeStepVO.setStrUserName(adminApprovalVO.getStrUserName());
		completeStepVO.setgName(clientCompanyReq.getCcNameEng());
		completeStepVO.setgEmail(clientCompanyReq.getCcEmail());
		completeStepVO.setgCustomerMsg(adminApprovalVO.getStrUserNotification());
		completeStepVO.setnIncidentNumber(Integer.parseInt(adminApprovalVO.getStrIncidentNo()));
		
		return completeStepVO;
	}

	@Transactional
	public void undoReviewNonClientCompany(AdminApprovalVO adminApprovalVO, String strTrakheesId) {
		AppMetaData appMetaData = appMetaDataDomainObjectManager.findByPrimaryKeyProcessAndStepCode(adminApprovalVO
				.getStrApplicationId().toString(), adminApprovalVO.getProcessCode().getProcessCode(), adminApprovalVO.getStrStepName());

		if (appMetaData != null) {
			adminApprovalVO.setStrApplnStatus(ConstantsCommon.IN_PROGRESS);
			getMapper().map(adminApprovalVO, appMetaData);
			
			this.appMetaDataDomainObjectManager.undoUpdateAppMetaDataWithActionTaken(appMetaData, adminApprovalVO.getStrStepName());
			
			ClientCompanyReq clientCompanyReq = nonClientCompanyDomainObjectManager.getNonClientCompanyByApplicationId(adminApprovalVO.getStrApplicationId());
	    	clientCompanyReq.setCcStatus(ConstantsCommon.IN_PROGRESS);
		    nonClientCompanyDomainObjectManager.update(clientCompanyReq);
		    
			if(nonClientCompanyWF.getFinDeptStepName().equalsIgnoreCase(adminApprovalVO.getStrStepName()) && adminApprovalVO.getStrActionType().equals(ConstantsCommon.APPROVE)){
			    	// If Approved by Finance department, send the approval message to the Ultimus alone and update the application request in the DB as approved
					clientCompanyReq.setCcStatus(ConstantsCommon.CLIENT_STATUS_INACTIVE);
			    	this.singleClientCompanyDomainObjectManager.undoCreateCompany(clientCompanyReq, strTrakheesId);
			}
			appMetaData.setWfStatus(ConstantsCommon.IN_PROGRESS);
			appMetaData.setWfStatusEn(adminApprovalVO.getStrInProgressStatusEn());
			appMetaData.setWfStatusAr(adminApprovalVO.getStrInProgressStatusAr());
			appMetaDataDomainObjectManager.update(appMetaData);
		}
	}
}
